<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Arrow</title>
<script type="text/javascript">
    /**
     * Author:@Freid
     * Date:2014年11月5日23:33:28
     * Version:1.1
     */

    //TODO:把所有计算用的数字换成变量运算，并且根据设备屏幕进行自适应调整
    var worldSize = [280, 500];
    var gameWorld;
    var painter;
    var gameInterval;
	var cubeInterval;
	var cubeSpeed;
	var cubeSize;
	var cubes;		//cube队列，用于存储游戏中的下落小方块
	var hitCubes;	//cube队列，用于存储已经被击中的方块，在击中动画结束后方块应该被销毁
	var actived;
	var missed;
	var missField;
	var score;
	var speedUpCount;
    var currentScene;   //0 for main menu, 1 for game, 2 for instruction.
	
	var Cube;
    Cube = {

        addNewCube: function () {

            var cube = { position: [0, 0], hit: -1 };
            cube.position[0] = Math.round(Math.random() * 3);	//0,1,2,3
            if (cubes.length == 0) {
                cube.position[1] = -cubeSize;
            } else {
                cube.position[1] = cubes[cubes.length - 1].position[1] - cubeSize;
            }
            cubes.push(cube);
        }

    };
    
    function preLoad() {

        gameWorld = document.getElementById("_gamerWorld");
        gameWorld.focus();
        worldSize[0] = gameWorld.width;
        worldSize[1] = gameWorld.height;
        painter = gameWorld.getContext("2d");
        gameWorld.addEventListener("keypress", keyPressEventHandler, true);
        gameWorld.addEventListener("touchstart", touchEventHandler, true);
        gameInterval = setInterval(gamePlay, 500 / 34);    //game main process begin
        valueInit();
        drawGame();
    }

    function valueInit() {
        cubes = new Array();
        hitCubes = new Array();
        cubeSpeed = 15;
        cubeSize = 70;
        actived = [0,0,0,0];
        missed = false;
        missField = -1;
        score = 0;
        speedUpCount = 0;
        if (currentScene == 1) {
            clearInterval(cubeInterval);    //just in case
            cubeInterval = setInterval(cubeUpdate, 500 / cubeSpeed);
        } else
            currentScene = 0;
    }

    function gamePlay() {    //game main process
        gameWorld.focus();
        gameUpDate();
        drawGame();
    }
    
    function drawGame() {   //draw method, paint every thing in game
		painter.clearRect(0, 0, worldSize[0], worldSize[1]);

        //如果是主菜单
        if (currentScene == 0) {
            painter.beginPath();
            painter.moveTo(53,195);
            painter.lineTo(227,195);
            painter.lineWidth=51;
            painter.strokeStyle='#000000';
            painter.lineCap='round';
            painter.stroke();

            painter.beginPath();
            painter.moveTo(53,195);
            painter.lineTo(227,195);
            painter.lineWidth=50;
            painter.strokeStyle='#7CCD7C';
            painter.stroke();

            painter.beginPath();
            painter.moveTo(53,265);
            painter.lineTo(227,265);
            painter.lineWidth=51;
            painter.strokeStyle='#000000';
            painter.lineCap='round';
            painter.stroke();

            painter.beginPath();
            painter.moveTo(53,265);
            painter.lineTo(227,265);
            painter.lineWidth=50;
            painter.strokeStyle='#7CCD7C';
            painter.stroke();

            painter.fillStyle = "#404040"
            painter.font = "30px 仿宋";
            painter.fillText("开始游戏[Q]", 58, 206);
            painter.fillText("游戏说明[W]", 58, 276);

        }
        else if (currentScene == 1){

            /**
            * 开始绘制游戏背景
            */
            if (missed) {
                painter.fillStyle = "#FF7256";
                painter.fillRect(missField * cubeSize, 0, cubeSize, worldSize[1]);
            }

            painter.fillStyle = "#a0a0a0";
            for (var i = 0; i < 4; i++){
                if (actived[i] > 0) {
                    painter.fillRect(i * cubeSize, 430, cubeSize, cubeSize);
                }
            }

            painter.strokeStyle = "#c3c3c3";
            painter.lineWidth = 2;
            painter.fillStyle = "#c3c3c3";
            painter.font = "30px Arial";

            painter.beginPath();
            painter.moveTo(cubeSize, 0);
            painter.lineTo(cubeSize, worldSize[1]);
            painter.stroke();
            painter.closePath();

            painter.beginPath();
            painter.moveTo(cubeSize*2, 0);
            painter.lineTo(cubeSize*2, worldSize[1]);
            painter.stroke();
            painter.closePath();

            painter.beginPath();
            painter.moveTo(cubeSize*3, 0);
            painter.lineTo(cubeSize*3, worldSize[1]);
            painter.stroke();
            painter.closePath();

            painter.beginPath();
            painter.moveTo(0, worldSize[1] - cubeSize);
            painter.lineTo(worldSize[0], worldSize[1] - cubeSize);
            painter.stroke();
            painter.closePath();

            painter.fillText("Q", 22, 475);
            painter.fillText("W", 22 + cubeSize, 475);
            painter.fillText("E", 25 + cubeSize * 2, 475);
            painter.fillText("R", 25 + cubeSize * 3, 475);
            // 游戏背景绘制结束

            /**
            * 开始绘制Cube
            */
            painter.fillStyle = "#A3A3A3";
            for(var i = 0; i < cubes.length; i++) {
                painter.fillRect(cubes[i].position[0] * cubeSize, cubes[i].position[1], cubeSize, cubeSize);
            }

            for(var i = 0; i < hitCubes.length; i++) {
                var styleString = 111111 * hitCubes[i].hit;
                styleString = "#" + (999999 - styleString);
                painter.fillStyle = "#CCCCCC";
                painter.fillRect(hitCubes[i].position[0] * cubeSize, hitCubes[i].position[1], cubeSize, cubeSize);
            }
            // Cube绘制结束

            if (missed) {
                painter.beginPath();
                painter.moveTo(73,255);
                painter.lineTo(207,255);
                painter.lineWidth=51;
                painter.strokeStyle='#000000';
                painter.lineCap='square';
                painter.stroke();

                painter.beginPath();
                painter.moveTo(73,255);
                painter.lineTo(207,255);
                painter.lineWidth=50;
                painter.strokeStyle='#EEE9BF';
                painter.stroke();

                painter.beginPath();
                painter.moveTo(53,215);
                painter.lineTo(227,215);
                painter.lineWidth=51;
                painter.strokeStyle='#000000';
                painter.lineCap='round';
                painter.stroke();

                painter.beginPath();
                painter.moveTo(53,215);
                painter.lineTo(227,215);
                painter.lineWidth=50;
                painter.strokeStyle='#7CCD7C';
                painter.stroke();
                painter.fillStyle = "#FF0000";
                painter.font = "30px 仿宋";
                painter.fillText("你失手了！", 73, 225);
                painter.fillStyle = "#404040";
                painter.fillText("得分: " + score, 83, 270);

                painter.beginPath();
                painter.moveTo(53,305);
                painter.lineTo(227,305);
                painter.lineWidth=51;
                painter.strokeStyle='#000000';
                painter.lineCap='round';
                painter.stroke();

                painter.beginPath();
                painter.moveTo(53,305);
                painter.lineTo(227,305);
                painter.lineWidth=50;
                painter.strokeStyle='#7CCD7C';
                painter.stroke();
                painter.fillStyle = "#404040";
                painter.font = "30px 仿宋";
                painter.fillText("不服再来[Q]", 58, 317);

            }
        }
        else {
            painter.fillStyle = '#000000';
            painter.fillRect(30,100,220,300);
            painter.fillStyle = '#7CCD7C';
            painter.fillRect(31,101,218,298);
            painter.fillStyle = "#404040"
            painter.font = "20px 黑体";
            painter.fillText("游戏说明:",40,130,160);
            painter.fillText("按照方块下落的先后",40,150,200);
            painter.fillText("顺序按Q、W、E、R来",40,170,200);
            painter.fillText("消除对应列的方块.",40,190,200);
            painter.fillText("移动设备可以点击下",40,210,200);
            painter.fillText("方的Q、W、E、R按钮",40,230,200);
            painter.font = "14px 黑体";
            painter.fillText("输入任意键（单击）返回",60,380,200);
        }
    }
	
    function gameUpDate() { //判断hit还是miss
        
		for (var i = 0; i < 4; i++)
			if (actived[i] > 0)
				actived[i] --;
		
		for (var i = 0; i < hitCubes.length; i++) {
			if (hitCubes[i].hit <= 0) {
				hitCubes.splice(i,1);
				continue;
			} 
			hitCubes[i].hit --;
		}
    }
	
	function cubeUpdate() {	//移动方块，创造方块，销毁方块
		if (cubes.length < 10) 
			Cube.addNewCube();
		for (var i = 0; i < cubes.length; i++) {
			cubes[i].position[1] += 5;
		}
		for (var i = 0; i < hitCubes.length; i++) {
			hitCubes[i].position[1] += 5;
		}
		//if miss
		if (cubes[0].position[1] >= 500) {
			var cube = cubes.pop();
			cubeResult(0,cubes.shift());
		}
	}
    
    function keyPressEventHandler(e) {
        e.preventDefault();

		var inputField = -1;
        var keyID = e.keyCode ? e.keyCode :e.which;
		if(keyID == 87 || keyID == 119)  { // w
			inputField = 1;
        }
        if(keyID == 82 || keyID == 114)  { // r
            inputField = 3;
        }
        if(keyID == 69 || keyID == 101)  { //e
            inputField = 2;
        }
        if(keyID == 81 || keyID == 113)  { // q
            inputField = 0;
        }

        inputDealer(inputField);
    }

    function touchEventHandler(e) {
        e.preventDefault();
        var position = getPos(gameWorld, e);
        var inputField = -1;
        if (currentScene == 0) {
            if (position.x < 28 || position.x > 253)
                return ;

            if (position.y > 168 && position.y < 222)
                inputField = 0;

            if (position.y > 240 && position.y < 291)
                inputField = 1;
        }
        else if (currentScene == 1) {
            if (missed) {
                if(position.y > 280 && position.y <331 && position.x > 28 && position.x < 253)
                    inputField = 0;
            } else {
                if (position.y < 420 || position.y > 510 )
                    return;

                if (position.x > 0 && position.x < cubeSize )
                    inputField = 0;

                if (position.x >= cubeSize && position.x < cubeSize*2 )
                    inputField = 1;

                if (position.x >= cubeSize*2 && position.x < cubeSize*3 )
                    inputField = 2;

                if (position.x >= cubeSize*3 && position.x < worldSize[0] )
                    inputField = 3;
            }

        }
        inputDealer(inputField);
    }

    function inputDealer(inputField) {

        if (currentScene == 0) {
            if (inputField == 0) {
                currentScene = 1;
                cubeInterval = setInterval(cubeUpdate, 500 / cubeSpeed);
            }
            if (inputField == 1)
                currentScene = 2;
        }
        else if (currentScene == 1) {

            if (inputField == -1)
                return;

            if (missed) {
                if ( inputField == 0) {
                    valueInit();
                    missed = false;
                }
            } else {
                actived[inputField] = 4;
                if (cubes[0].position[0] != inputField) {
                    //if miss
                    cubeResult(0, inputField);
                } else {
                    //if hit
                    cubeResult(1, inputField);
                }
            }
        }
        else {
            currentScene = 0;
        }
    }
    
	function cubeResult(result,field) {
		//result 0 for miss 1 for hit
		if (result == 1) {
			score ++;
			var cube = cubes.shift();
			cube.hit = 4;
			hitCubes.push(cube);
			speedUpCount ++;
			if (speedUpCount > cubeSpeed*cubeSpeed/25 ) {
				cubeSpeed += 1;
				clearInterval(cubeInterval);
				cubeInterval = setInterval(cubeUpdate, 500 / cubeSpeed);
				speedUpCount = 0;
			}
			
		} else {
			missed = true;
			missField = field;
			clearInterval(cubeInterval);
		}
	}
	
    function gameOver() {
        clearInterval(gameInterval);
		clearInterval(cubeInterval);
    }

    function getPos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        var touch = evt.touches[0];
        return {
            x: touch.clientX - rect.left * (canvas.width / rect.width),
            y: touch.clientY - rect.top * (canvas.height / rect.height)
        }
    }

	function log() {
		console.log(cubes.length);
		for (var i=0; i < cubes.length; i++) {
			console.log(cubes[i].position[1]);
		}
	}
</script>
</head>
<body>
<div style="float: left; width: 300">
<canvas height="500" width="280" id="_gamerWorld" tabindex="0" style="border:2px solid #c3c3c3;">
您的浏览器不支持canvas
</canvas>
</div>
<script>
    preLoad();
</script>
</body>
</html>